﻿namespace BM.Tools.WebControls.MForm.Example.Toolbox
{
    using System;
    using System.IO;
    using System.Text;
    using System.Web.UI.WebControls;
    using System.Xml;

    using BM.Tools.WebControls.MForm.Controls;
    using BM.Tools.WebControls.MForm.Controls.Items;

    public partial class MFormToolbox : System.Web.UI.UserControl
    {
        private ToolBoxData data;        

        public ToolBoxData Data
        {
            get
            {
                if (data == null)
                {
                    data = ToolBoxData.Load(actionMForm.OutputXml);
                }

                return data;
            }
        }

        public Root MFormRoot
        {
            get;
            set;
        }

        public Button NoValidationButton
        {
            get
            {
                return noValidationButton;
            }
        }

        public Button ValidationButton
        {
            get
            {
                return validationButton;
            }
        }

        /// <summary>
        /// Gets or sets a value indicating whether the toolbox is visible.
        /// </summary>
        public override bool Visible
        {
            get
            {
                return MFormRoot != null && base.Visible;
            }

            set
            {
                base.Visible = value;
            }
        }

        public static StringBuilder GetBuilder(XmlDocument doc)
        {
            var settings = new XmlWriterSettings
                           {
                                   Indent = true
                           };
            var builder = new StringBuilder();
            using (var xmlWriter = XmlWriter.Create(new StringWriter(builder), settings))
            {
                doc.WriteTo(xmlWriter);
            }

            return builder;
        }

        public static string GetEncodedOutput(XmlDocument doc)
        {
            StringBuilder builder = GetBuilder(doc);
            return builder.Replace("&", "&amp;").Replace(">", "&gt;").Replace("<", "&lt;").ToString();
        }

        protected void ActionClick(object sender, EventArgs e)
        {
            switch (Data.ActionType)
            {
                case ToolBoxActionType.SetMode:
                    PerformAction(item => item.Mode = Data.Mode);
                    break;
                case ToolBoxActionType.SetRequirement:
                    PerformAction(SetRequirement);
                    break;
                case ToolBoxActionType.SetStyle:
                    PerformAction(SetStyle);
                    break;
                case ToolBoxActionType.SetVisibility:
                    PerformAction(item => item.Visible = Data.Visible);
                    break;
            }
        }

        protected void NoValidationButton_Click(object sender, EventArgs e)
        {
            CreateOutput(MFormRoot.OutputXml);
        }

        protected void Page_Load(object sender, EventArgs e)
        {
            actionMForm.Visible = Core.Navigation.ToolBoxNavigationEnabled;
            actionMFormValidator.Visible = actionMForm.Visible;
            navigationDiv.Visible = !actionMForm.Visible;
        }

        protected void ValidationButton_Click(object sender, EventArgs e)
        {
            CreateOutput(MFormRoot.OutputXml);
        }

        private void CreateOutput(XmlDocument document)
        {
            output.Text = GetEncodedOutput(document);
        }

        private void PerformAction(Action<OffspringItem> action)
        {
            foreach (var item in MFormRoot.Select(Data.XPath))
            {
                action(item);
            }
        }


        private void SetRequirement(OffspringItem item)
        {
            var leafItem = item as LeafItem;
            if (leafItem == null)
            {
                return;
            }

            leafItem.IsOptional = !Data.Required;
        }

        private void SetStyle(OffspringItem item)
        {
            foreach (var keyValue in Data.Styles)
            {
                item.Style.Add(keyValue.Key, keyValue.Value);
            }
        }
    }
}